package com.oem.upgrade;

import static com.oem.upgrade.Constants.MDFU_ERR_COMMUNICATE_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_DATA_TRANSFER_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_END_TRANSFER_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_FILE_NOT_EXIST;
import static com.oem.upgrade.Constants.MDFU_ERR_FILE_NOT_SELECT;
import static com.oem.upgrade.Constants.MDFU_ERR_GET_CLIENT_INFO_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_IMAGE_STATE_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_SOCKET_FAIL;
import static com.oem.upgrade.Constants.MDFU_ERR_START_TRANSFER_FAIL;
import static com.oem.upgrade.Constants.MDFU_SUCCESS;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity {

    private static final int SENDPORT = 10000;
    private static final int RECEIVEPORT = 10001;
    private static final String SERVERADDRESS = "127.0.0.1";
    private static final String filePath = "/sdcard/Download/AvironUCB_V2.img";
    private static final String TAG = "UPGRADE_FIRMWARE";
    private static final int REQUEST_PERMISSION_CODE = 100;

    private TextView textViewFilePath;
    private String selectedFilePath = null;  // 存储选择的文件路径
    private static final int FILE_SELECT_CODE = 1;

    private final ExecutorService executorService = Executors.newSingleThreadExecutor();
    private final Handler mainHandler = new Handler(Looper.getMainLooper());

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 直接检查 READ_EXTERNAL_STORAGE 权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSION_CODE);
        }

        Button buttonSelectFile = findViewById(R.id.buttonSelectFile);
        textViewFilePath = findViewById(R.id.textViewFilePath);
        buttonSelectFile.setOnClickListener(v -> openFileSelector());
        Button buttonStartUpgrade = findViewById(R.id.buttonStartUpgrade);

        buttonStartUpgrade.setOnClickListener(v -> {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {

                executorService.execute(() -> {
                    int code = startUpgrade();
                    mainHandler.post(() -> Toast.makeText(this, "状态码为 " + code, Toast.LENGTH_SHORT).show());
                });

            } else {
                Toast.makeText(this, "请先授予存储权限", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startUpgrade();
            } else {
                Toast.makeText(this, "权限被拒绝，无法读取文件", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 打开文件选择器
    private void openFileSelector() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");  // 可以限制为特定文件类型如 "application/octet-stream"
        startActivityForResult(intent, FILE_SELECT_CODE);
    }

    // 处理文件选择结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == FILE_SELECT_CODE && resultCode == RESULT_OK) {
            Uri uri = data.getData();
            if (uri != null) {
                selectedFilePath = getFilePathFromUri(uri);
                textViewFilePath.setText(selectedFilePath != null ? selectedFilePath : "文件路径获取失败");
            }
        }
    }

    private String getFilePathFromUri(Uri uri) {
        String filePath = null;

        if ("content".equalsIgnoreCase(uri.getScheme())) {
            String[] projection = {MediaStore.MediaColumns.DATA};
            Cursor cursor = null;
            try {
                cursor = getContentResolver().query(uri, projection, null, null, null);
                if (cursor != null && cursor.moveToFirst()) {
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
                    filePath = cursor.getString(column_index);
                }
            } catch (Exception e) {
                Log.e(TAG, "Error getting file path: " + e.getMessage());
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }

            // 如果 MediaColumns.DATA 返回为空，尝试用文件流处理
            if (filePath == null) {
                filePath = copyUriToCache(uri);
            }

        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            filePath = uri.getPath();
        }

        Log.d(TAG, "filePath is " + filePath);
        return filePath;
    }

    private String copyUriToCache(Uri uri) {
        File cacheDir = getCacheDir();
        String fileName = "temp_file_" + System.currentTimeMillis();

        try {
            InputStream inputStream = getContentResolver().openInputStream(uri);
            File outFile = new File(cacheDir, fileName);
            OutputStream outputStream = new FileOutputStream(outFile);

            byte[] buffer = new byte[1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }

            inputStream.close();
            outputStream.close();

            Log.d(TAG, "File copied to cache: " + outFile.getAbsolutePath());
            return outFile.getAbsolutePath();

        } catch (Exception e) {
            Log.e(TAG, "Error copying file to cache: " + e.getMessage());
            return null;
        }
    }

    // 启动升级逻辑
    private int startUpgrade() {

        if (selectedFilePath == null) {
            Log.e(TAG, "请先选择升级文件");
            return MDFU_ERR_FILE_NOT_SELECT;
        }

        // 读取文件内容
        Log.d(TAG, "The File Path is " + selectedFilePath);
        byte[] bytes = readFiles(selectedFilePath);
        if (bytes == null) {
            Log.e(TAG,"读取文件失败" );
            return MDFU_ERR_FILE_NOT_EXIST;
        }

        // 调用升级 API
        UpgradeAPI upgradeAPI = new UpgradeAPI();
        int statueCode = upgradeAPI.runUpgradeUcb(SERVERADDRESS, SENDPORT, RECEIVEPORT, bytes);

        Log.d(TAG, "The Status Code is : " + statueCode);

        onFirmwareUpgradeResult(statueCode);
        return statueCode;
    }

    // 读取文件为字节数组
    private byte[] readFiles(String path) {
        try {
            File file = new File(path);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int read;
            while ((read = fis.read(buffer)) != -1) {
                bos.write(buffer, 0, read);
            }
            fis.close();
            return bos.toByteArray();
        } catch (Exception e) {
            Log.e(TAG, "Error reading file: " + e.getMessage());
            return null;
        }
    }

    public void onFirmwareUpgradeResult(int statusCode) {
        switch (statusCode) {
            case MDFU_SUCCESS:
                Log.i(TAG, "Firmware upgrade successful!");
                break;

            case MDFU_ERR_SOCKET_FAIL:
                Log.e(TAG, "Failed to initialize send socket.");
                break;

            case MDFU_ERR_GET_CLIENT_INFO_FAIL:
                Log.e(TAG, "Failed to get client info.");
                break;

            case MDFU_ERR_START_TRANSFER_FAIL:
                Log.e(TAG, "Failed to start data transfer.");
                break;

            case MDFU_ERR_DATA_TRANSFER_FAIL:
                Log.e(TAG, "Data block transmission failed.");
                break;

            case MDFU_ERR_IMAGE_STATE_FAIL:
                Log.e(TAG, "Failed to verify image state.");
                break;

            case MDFU_ERR_END_TRANSFER_FAIL:
                Log.e(TAG, "Failed to end data transfer.");
                break;

            case MDFU_ERR_COMMUNICATE_FAIL:
                Log.e(TAG, "Failed to communicate with UCB.");
                break;

            default:
                Log.e("Upgrade", "Unknown error occurred. Code: " + statusCode);
        }
    }

}
